/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package downloadmanager.downloader;

import downloadmanager.event.XEvent;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.Date;
import util.Converter;
import util.DateExtensions;

/**
 *
 * @author Administrator
 */
public class DownloadSegment {

    private long startPosition;
    private int index;
    private String currentURL;
    private long initialStartPosition;
    private long endPosition;
    private RandomAccessFile outputStream;
    private InputStream inputStream;
    private Exception lastError;
    private DownloadSegmentState state;
    private boolean started = false;
    private Date lastReception = null;
    private Date lastErrorDateTime = null;
    private double rate;
    private long start;
    private long left = 0;
    private int currentTry;
    public final XEvent<Object> ValueChange = new XEvent<Object>();

    public int getCurrentTry() {
        return currentTry;
    }

    public void setCurrentTry(int value) {
        currentTry = value;
    }

    public DownloadSegmentState getState() {
        return state;
    }

    public void setState(DownloadSegmentState value) {
        state = value;

        switch (state) {
            case Downloading:
                beginWork();
                break;

            case Connecting:
            case Paused:
            case Finished:
            case Error:
                rate = 0.0;
                left = 0;
                break;
        }
    }

    public Date getLastErrorDateTime() {
        return lastErrorDateTime;
    }

    public Exception getLastError() {
        return lastError;
    }

    public void setLastError(Exception value) {
        if (value != null) {
            lastErrorDateTime = new Date();
        } else {
            lastErrorDateTime = null;
        }
        lastError = value;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int value) {
        index = value;
    }

    public long getInitialStartPosition() {
        return initialStartPosition;
    }

    public void setInitialStartPosition(long value) {
        initialStartPosition = value;
    }

    public long getStartPosition() {
        return startPosition;
    }

    public void setStartPosition(long value) {
        startPosition = value;
        ValueChange.fire(this, null);
    }

    public long getTransfered() {
        return startPosition - initialStartPosition;
    }

    public long getTotalToTransfer() {
        return (endPosition <= 0 ? 0 : endPosition - initialStartPosition);
    }

    public long getMissingTransfer() {
        return (endPosition <= 0 ? 0 : endPosition - startPosition);
    }

    public double getProgress() {
        return (endPosition <= 0 ? 0 : ((double) getTransfered() / (double) getTotalToTransfer() * 100.0f));
    }

    public long getEndPosition() {
        return endPosition;
    }

    public void setEndPosition(long value) {
        endPosition = value;
        ValueChange.fire(this, null);
    }

    public RandomAccessFile getOutputStream() {
        return outputStream;
    }

    public void setOutputStream(RandomAccessFile value) {
        outputStream = value;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream value) {
        inputStream = value;
    }

    public String getCurrentURL() {
        return currentURL;
    }

    public void setCurrentURL(String value) {
        currentURL = value;
    }

    public double getRate() {
        if (state == DownloadSegmentState.Downloading) {
            increaseStartPosition(0);
            return rate;
        } else {
            return 0;
        }
    }

    public long getLeft() {
        return left;
    }

    public void beginWork() {
        start = startPosition;
        lastReception = new Date();
        started = true;
    }

    public synchronized void increaseStartPosition(long size) {
        Date now = new Date();

        startPosition += size;

        if (started) {
            long ts = DateExtensions.getDeltaSeconds(lastReception, now);
            if (ts == 0) {
                return;
            }

            // bytes per seconds
            rate = ((double) (startPosition - start)) / ts;

            if (rate > 0.0) {
                left = Converter.toLong(getMissingTransfer() / rate);
            } else {
                left = Long.MAX_VALUE;
            }
        } else {
            start = startPosition;
            lastReception = now;
            started = true;
        }
        ValueChange.fire(this, null);
    }
}
